#pragma once

#include <iostream>
#include <list>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <algorithm>
#include "Internet.hpp"
#include "Log.hpp"
#include "Mutex.hpp"

using namespace LogModule;
using namespace Lock;

class Userinterface
{
    public:
    virtual ~Userinterface() = default ;
    virtual void SendTo(int sockfd, const std::string &message) = 0;
    virtual bool operator==(const InetAddr &u) = 0;
    virtual std::string Id() = 0;
     

};

class User :public Userinterface
{
    public:
    User(InetAddr inaddr)
    :_inaddr(inaddr)
    {

    }
    void SendTo(int sockfd, const std::string &message) override
    {
        LOG(LogLevel::DEBUG) << "send message to " << _inaddr.Addr() << " info: " << message;
        auto n = ::sendto(sockfd, message.c_str() ,message.size(),0,_inaddr.Addptr(),_inaddr.Sizeptr());
        (void)n;
    }
    bool operator==(const InetAddr &u)
    {
        return _inaddr == u;
    }
    std::string Id()
    {
        return _inaddr.IP();
    }
    ~User()
    {

    }
    private:
    InetAddr _inaddr;

};

class Usermanger
{
    public:
    Usermanger()
    {

    }
    ~Usermanger()
    {

    }
    void AddUSer(InetAddr& user)
    {
        LockGuard lockguard(_mutex);
        for(auto& e : _online_user)
        {
            if( *e == user )
            {
                std::cout<<e->Id()<<" 用户已经存在"<<std::endl; 
                return;
            }
        }
        _online_user.push_back(std::make_shared<User>(user));
        LOG(LogLevel::DEBUG)<<"已添加 用户"<<user.Addr();

    }
    void DelUser(InetAddr& user)
    {
        LockGuard lockguard(_mutex);
        LOG(LogLevel::DEBUG)<<"已删除 用户";
         auto pos = std::remove_if(_online_user.begin(), _online_user.end(), [&user](std::shared_ptr<Userinterface> &tmp){
            return *tmp == user;
        });
        _online_user.erase(pos, _online_user.end());

    }
    void Router(int sockfd,const std::string& message)
    {
        LockGuard lockguard(_mutex);
        for(auto& e : _online_user)
        {
            e->SendTo(sockfd,message);
        }
    }
    private:
    std::list<std::shared_ptr<Userinterface>> _online_user;
    Mutex _mutex;

};